package com.wswy.wzcx.widget.shadow;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import com.blankj.utilcode.util.SizeUtils;
import com.wswy.wzcx.R;

public class ShadowFrameLayout extends FrameLayout {

  private static final String TAG = "ShadowFrameLayout";





  private int shadowColor;
  private int elevation;
  private float cornerRadius;

  private Shadow ambientShadow,spotShadow;
  private PorterDuffColorFilter shadowColorFilter;
  private RectF shadowMaskRect = new RectF();

  private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG);
  public static PorterDuffXfermode CLEAR_MODE = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);

  public ShadowFrameLayout(@NonNull Context context) {
    this(context,null);
  }

  public ShadowFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
    this(context, attrs,0);
  }

  public ShadowFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowFrameLayout);
    shadowColor = typedArray.getColor(R.styleable.ShadowFrameLayout_sf_shadowColor, 0);
    elevation = typedArray.getDimensionPixelSize(R.styleable.ShadowFrameLayout_sf_shadowElevation, SizeUtils.dp2px(5));
    cornerRadius = typedArray.getDimensionPixelSize(R.styleable.ShadowFrameLayout_sf_cornerRadius, SizeUtils.dp2px(3));

    typedArray.recycle();


//    elevation = SizeUtils.dp2px(5);
//    cornerRadius = SizeUtils.dp2px(3);

    if(shadowColor != 0){
      shadowColorFilter = new PorterDuffColorFilter(shadowColor,PorterDuff.Mode.MULTIPLY);
    }
  }

  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
  public ShadowFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowFrameLayout);
    shadowColor = typedArray.getColor(R.styleable.ShadowFrameLayout_sf_shadowColor, 0);
    elevation = typedArray.getDimensionPixelSize(R.styleable.ShadowFrameLayout_sf_shadowElevation, SizeUtils.dp2px(5));
    cornerRadius = typedArray.getDimensionPixelSize(R.styleable.ShadowFrameLayout_sf_cornerRadius, SizeUtils.dp2px(3));

    typedArray.recycle();


//    elevation = SizeUtils.dp2px(5);
//    cornerRadius = SizeUtils.dp2px(3);

    if(shadowColor != 0){
      shadowColorFilter = new PorterDuffColorFilter(shadowColor,PorterDuff.Mode.MULTIPLY);
    }
  }



  @Override
  protected boolean drawChild(Canvas canvas, View child, long drawingTime) {

    if(child instanceof ShadowFrameLayout){
      ((ShadowFrameLayout) child).drawShadow(canvas);
    }
    return super.drawChild(canvas, child, drawingTime);
  }


  public void drawShadow(Canvas canvas) {

    if(shadowColorFilter == null){
      return;
    }

    float z = elevation;

    int cornerRadius = (int) this.cornerRadius;
    if(ambientShadow == null){

      ambientShadow = ShadowGenerator.generateShadow(this, z,cornerRadius);
      //spotShadow = ShadowGenerator.generateShadow(this, z / getResources().getDisplayMetrics().density,cornerRadius);
    }

    int saveCount = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);

    Matrix matrix = getMatrix();
    canvas.save();
    canvas.translate(getLeft(),getTop());
    canvas.concat(matrix);
    ambientShadow.draw(canvas, this, paint, shadowColorFilter);
    canvas.restore();


//    canvas.save();
//    canvas.translate(this.getLeft(), this.getTop() + z / 2);
//    canvas.concat(matrix);
//    spotShadow.draw(canvas, this, paint, shadowColorFilter);
//    canvas.restore();

    if(saveCount != 0) {
      canvas.translate(this.getLeft(), this.getTop());
      canvas.concat(matrix);
      paint.setXfermode(CLEAR_MODE);
    }

    shadowMaskRect.set(0, 0, getWidth(), getHeight());
    canvas.drawRoundRect(shadowMaskRect, cornerRadius, cornerRadius, paint);

    if (saveCount != 0) {
      canvas.restoreToCount(saveCount);
      paint.setXfermode(null);
    }
  }



  public void setElevationShadowColor(int color) {
    if(shadowColor!= color){

      shadowColor = color;
      shadowColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY);

      invalidateParentIfNeeded();
    }

  }

  public void setElevationLength(int elevation) {
    if(this.elevation != elevation){
      this.elevation = elevation;
      invalidateParentIfNeeded();
    }
  }

  public void setElevationCornerRadius(float cornerRadius) {
    if(this.cornerRadius != cornerRadius){

      this.cornerRadius = cornerRadius;
      invalidateParentIfNeeded();
    }
  }

  private void invalidateParentIfNeeded() {

    if (getParent() == null || !(getParent() instanceof View)) {
      return;
    }

    postInvalidate();

  }

}
